package work

import (
	"seat-service/initialization"
	"seat-service/model"
	"seat-service/model/dto"
	"strconv"
	"strings"
	"time"
)

type ApplicationHandler struct{}

func (h *ApplicationHandler) Handle(channel, message string) {
	memberArr := strings.Split(message, ",")
	openid, dataMap := retrieve(memberArr[0])
	if dataMap == nil {
		initialization.SeatLogger.Error("预约提醒服务异常，无法获取数据，学生id:" + message + ",正在重试")
		return
	}
	err := PushWX("Fejh7CaQVC7SLsn-NOlOj_oCwsaVDxT-ZGxdVVd9kK0", "", strconv.Itoa(openid), InitFormat(dataMap), "formal", "zh_CN")
	if err != nil {
		initialization.SeatLogger.Error("推送异常，学生id:" + message + ",正在重试")
		go retry(channel, message)
		return
	}
	initialization.SeatLogger.Info("推送成功，学生id:" + message)
}

func retry(channel, message string) {
	count := 0
	var err error
	for count < 5 {
		openid, dataMap := retrieve(message)
		err = PushWX("Fejh7CaQVC7SLsn-NOlOj_oCwsaVDxT-ZGxdVVd9kK0", "", strconv.Itoa(openid), InitFormat(dataMap), "formal", "zh_CN")
		if err != nil {
			initialization.SeatLogger.Error("channel:" + channel + ",message:" + message + ",消息重试失败" + strconv.Itoa(count+1) + "次")
		} else {
			initialization.SeatLogger.Info("channel:" + channel + ",message:" + message + ",消息发送成功")
			return
		}
		count++
	}
	initialization.DB.Create(model.PushErr{
		Channel: channel,
		Message: message,
		Err:     "错误位置：预约提醒，错误:" + err.Error(),
	})
	initialization.SeatLogger.Error("channel:" + channel + ",message:" + message + ",消息重试次数到达阈值，已存入数据库")
}
func retrieve(message string) (int, map[string]string) {
	id, _ := strconv.Atoi(message)
	data := dto.AppointmentPushDto{}
	err := initialization.DB.Table("students s1").
		Joins("JOIN reserves r1 ON s1.id=r1.student_id").
		Joins("JOIN seats s2 ON r1.seat_id=s2.id").
		Joins("JOIN buildings b1 ON s2.building_id=b1.id").
		Select("s1.name AS student_name,b1.name,s2.seat_number,r1.appointment_time_start,r1.appointment_time_end,s1.openid").
		Where("s1.id=? AND r1.appointment_time_start>?", id, time.Unix(int64(id), 0)).
		Order("r1.appointment_time_start").
		Limit(1).
		First(&data).
		Error
	if err != nil {
		return 0, nil
	}
	start := data.AppointmentTimeStart.Format("2006/01/02 15:04")
	end := data.AppointmentTimeEnd.Format("2006/01/02 15:04")
	dataMap := map[string]string{
		"name1":   data.StudentName,
		"thing2":  data.Name,
		"thing46": data.SeatNumber,
		"time22":  start,
		"time23":  end,
	}
	return data.Openid, dataMap
}

//func PushAppointment(pool *utils.Pool) {
//	// 提交一些任务到协程池
//	for {
//		time.Sleep(time.Second)
//		task := &AppointmentTask{
//			redisClient: initialization.Redis,
//			zsetKey:     service2.Appointment,
//		}
//		pool.Submit(task)
//	}
//}
//
//// AppointmentTask 示例任务实现了Task接口
//type AppointmentTask struct {
//	redisClient *redis.Client // Redis客户端
//	zsetKey     string        // zset的键
//}
//
//// Execute 执行任务
//func (r *AppointmentTask) Execute() {
//	var z []redis.Z
//	var errZ error
//	z, errZ = r.redisClient.ZPopMin(context.Background(), r.zsetKey).Result()
//	if errZ != nil {
//		fmt.Println(errZ.Error())
//	} else if len(z) == 0 {
//
//	} else {
//		//删除读取到的数据
//		score := int64(z[0].Score)
//		member := z[0].Member.(string)
//		if score-time.Now().Unix() > 600 {
//			fmt.Println(score, time.Now().Unix())
//			a := score - time.Now().Unix() - 600 + 1
//			fmt.Println(member, "=======协程准备进入休眠，休眠时间：", a)
//			time.Sleep(time.Second * time.Duration(a))
//			fmt.Println("休眠检测:", a)
//		}
//		//处理数据,推送至小程序
//		id := z[0].Member
//		data := dto.AppointmentPushDto{}
//		err := initialization.DB.Table("students s1").
//			Joins("JOIN reserves r1 ON s1.id=r1.student_id").
//			Joins("JOIN seats s2 ON r1.seat_id=s2.id").
//			Joins("JOIN buildings b1 ON s2.building_id=b1.id").
//			Select("s1.name AS student_name,b1.name,s2.seat_number,r1.appointment_time_start,r1.appointment_time_end,s1.openid").
//			Where("s1.id=? AND r1.appointment_time_start>?", id, time.Unix(int64(z[0].Score), 0)).
//			Order("r1.appointment_time_start").
//			Limit(1).
//			First(&data).
//			Error
//		if err != nil {
//			initialization.SeatLogger.Error("推送异常，学生id:" + member)
//			return
//		}
//		start := data.AppointmentTimeStart.Format("2006/01/02 15:04")
//		end := data.AppointmentTimeEnd.Format("2006/01/02 15:04")
//		dataMap := make(map[string]string, 0)
//		dataMap["name1"] = data.StudentName
//		dataMap["thing2"] = data.Name
//		dataMap["thing46"] = data.SeatNumber
//		dataMap["time22"] = start
//		dataMap["time23"] = end
//		err = PushWX("Fejh7CaQVC7SLsn-NOlOj_oCwsaVDxT-ZGxdVVd9kK0", "", strconv.Itoa(data.Openid), InitFormat(dataMap), "formal", "zh_CN")
//		if err != nil {
//			initialization.SeatLogger.Error("推送异常，学生id:" + member)
//			return
//		}
//		initialization.SeatLogger.Info("推送成功，学生id:" + member)
//	}
//}

/*
==========================================================================================================================
*/
//func AppointmentPushDelay() {
//	w := delay.NewRedisZsetReader("appointment-push", initialization.Redis, 5, true)
//	w.StartRead(2, 100, pushDelay, 30)
//}
//func pushDelay(z redis.Z) {
//	score := int64(z.Score)
//	member := z.Member.(string)
//	if score-time.Now().Unix() > 600 {
//		fmt.Println(score, time.Now().Unix())
//		a := score - time.Now().Unix() - 600 + 1
//		fmt.Println(member, "=======协程准备进入休眠，休眠时间：", a)
//		time.Sleep(time.Second * time.Duration(a))
//		fmt.Println("休眠检测:", a)
//	}
//	//处理数据,推送至小程序
//	id := z.Member
//	data := dto.AppointmentPushDto{}
//	err := initialization.DB.Table("students s1").
//		Joins("JOIN reserves r1 ON s1.id=r1.student_id").
//		Joins("JOIN seats s2 ON r1.seat_id=s2.id").
//		Joins("JOIN buildings b1 ON s2.building_id=b1.id").
//		Select("s1.name AS student_name,b1.name,s2.seat_number,r1.appointment_time_start,r1.appointment_time_end,s1.openid").
//		Where("s1.id=? AND r1.appointment_time_start>?", id, time.Unix(int64(z.Score), 0)).
//		Order("r1.appointment_time_start").
//		Limit(1).
//		First(&data).
//		Error
//	if err != nil {
//		initialization.SeatLogger.Error("推送异常，学生id:" + member)
//		return
//	}
//	start := data.AppointmentTimeStart.Format("2006/01/02 15:04")
//	end := data.AppointmentTimeEnd.Format("2006/01/02 15:04")
//	dataMap := make(map[string]string, 0)
//	dataMap["name1"] = data.StudentName
//	dataMap["thing2"] = data.Name
//	dataMap["thing46"] = data.SeatNumber
//	dataMap["time22"] = start
//	dataMap["time23"] = end
//	err = PushWX("Fejh7CaQVC7SLsn-NOlOj_oCwsaVDxT-ZGxdVVd9kK0", "", strconv.Itoa(data.Openid), InitFormat(dataMap), "formal", "zh_CN")
//	if err != nil {
//		initialization.SeatLogger.Error("推送异常，学生id:" + member)
//		return
//	}
//	initialization.SeatLogger.Info("推送成功，学生id:" + member)
//}
